/*
 * Copyright 2011 Focus Technology, Co., Ltd. All rights reserved.
 */
package com.tfc.analysis.process;

import com.tfc.analysis.entity.Keyword;
import com.tfc.analysis.utils.AnalysisUtils;
import com.tfc.analysis.utils.StringUtils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 数据初始化处理器。主要是将敏感词解析为树状存储，这样以提高敏感词检索效率。
 *
 * @author taofucheng
 */
@SuppressWarnings({"rawtypes"})
public class DataInit {

    /**
     * 构造、生成敏感词库树。并返回所有敏感词中最短的词的长度。
     *
     * @param words     词库
     * @param wordsTree 聚合词库的树
     * @return 返回所有敏感词中最短的词的长度。
     */
    public static Map<Integer, Integer> generalWordTree(Set<Keyword> words, Map<String, Map> wordsTree) {
        int minLen = 0;
        int maxLen = 0;
        Map<Integer, Integer> ret = new HashMap<Integer, Integer>();
        if (words == null || words.isEmpty() || wordsTree == null) {
            wordsTree.clear();
            return ret;
        }
        /** 生成的临时词库树。用于在最后生成的时候一次性替换，尽量减少对正在查询时的干扰 */
        Map<String, Map> wordsTreeTmp = new HashMap<String, Map>();
        wordsTreeTmp.clear();
        for (Keyword w : words) {
            if (StringUtils.isBlank(w.getWord())) {
                continue;
            }
            if (minLen == 0) {
                minLen = w.getWordLength();
                maxLen = w.getWordLength();
            } else {
                if (w.getWordLength() < minLen) {
                    minLen = w.getWordLength();
                }
                if (w.getWordLength() > maxLen) {
                    maxLen = w.getWordLength();
                }
            }
            AnalysisUtils.makeTreeByWord(wordsTreeTmp, w.getWord(), w);
        }
        wordsTree.clear();
        wordsTree.putAll(wordsTreeTmp);
        ret.put(minLen, maxLen);
        return ret;
    }

    /**
     * 构建敏感词树
     *
     * @param sensitiveWords
     * @param sensitiveWordsTree
     * @param whiteWords
     * @param wordToWhite
     * @return 返回 最短的敏感词长度，和最长的白名单词的长度
     */
    public static Map<Integer, Integer> generalWhiteWordsTree(Set<Keyword> sensitiveWords, Map<String, Map> sensitiveWordsTree, Set<Keyword> whiteWords, Map<Keyword, Set<Keyword>> wordToWhite) {
        int minLen = 0;
        int maxLen = 0;
        Map<Integer, Integer> ret = new HashMap<Integer, Integer>();
        if (sensitiveWords == null || sensitiveWords.isEmpty() || sensitiveWordsTree == null) {
            sensitiveWordsTree.clear();
            wordToWhite.clear();
            return ret;
        }
        /** 生成的临时词库树。用于在最后生成的时候一次性替换，尽量减少对正在查询时的干扰 */
        Map<String, Map> wordsTreeTmp = new HashMap<String, Map>();
        Map<Keyword, Set<Keyword>> wordToWhiteTmp = new HashMap<Keyword, Set<Keyword>>();
        wordsTreeTmp.clear();
        for (Keyword w : sensitiveWords) {
            if (StringUtils.isBlank(w.getWord())) {
                continue;
            }
            if (minLen == 0) {
                minLen = w.getWordLength();
            } else {
                if (w.getWordLength() < minLen) {
                    minLen = w.getWordLength();
                }
            }
            //添加到树中
            AnalysisUtils.makeTreeByWord(wordsTreeTmp, w.getWord(), w);
            //处理对应关系
            if (whiteWords != null && whiteWords.size() > 0) {
                Set<Keyword> ks = new HashSet<Keyword>();
                for (Keyword k : whiteWords) {
                    if (StringUtils.isBlank(k.getWord())) {
                        continue;
                    }
                    if (k.getWord().contains(w.getWord())) {
                        if (maxLen == 0) {
                            maxLen = k.getWordLength();
                        } else {
                            if (w.getWordLength() > maxLen) {
                                maxLen = k.getWordLength();
                            }
                        }
                        ks.add(k);
                    } else {
                        for (int len = 1; len < w.getWordLength(); len++) {
                            String s = w.getWord().substring(len);//该词的后半部分，如果是白名单的开头，就是该敏感词的白名单
                            String e = w.getWord().substring(0, len);//该词的前半部分，如果是白名单的结尾，就是该敏感词的白名单
                            if (k.getWord().startsWith(s) || k.getWord().endsWith(e)) {
                                ks.add(k);
                            }
                        }
                    }
                }
                if (ks.size() > 0) {
                    wordToWhiteTmp.put(w, ks);
                }
            }
        }
        sensitiveWordsTree.clear();
        sensitiveWordsTree.putAll(wordsTreeTmp);
        wordToWhite.clear();
        wordToWhite.putAll(wordToWhiteTmp);
        ret.put(minLen, maxLen);
        return ret;
    }

}
